<?php
// +----------------------------------------------------------------------
// | B5Yii2CMF V3.0 [快捷通用基础管理开发平台]
// +----------------------------------------------------------------------
// | Author: 冰舞 <357145480@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace common\extend\plugins;

use yii\db\ActiveQuery;

class WithOneModelQuery
{

    /**
     * 适用于单条查询，简化多条查询
     * 例如 list是一个包含user_id的数组，现在需要每条添加userInfo键对应用户信息，则调用此方法
     *  WithOneModelQuery::listWithOneModel(User::find(), $list, 'userInfo');
     * @param ActiveQuery $query
     * @param array $list
     * @param string $withName
     * @param array $select
     * @param string $keyField
     * @return array
     */
    public static function listWithOneModel(ActiveQuery $query, array $list, string $withName, array $select = [], string $keyField = 'id')
    {
        if (!$list || !$withName || !$keyField) return $list;
        $idList = array_column($list, $keyField);
        $modelList =self::withOneModel($query, $idList, $select, $keyField);
        return self::bindWithOneList($list, $modelList, $withName, $select, $keyField);
    }

    /**
     * 适用于批量查询，简化多条查询
     * @param ActiveQuery $query
     * @param array $idList
     * @param array $select
     * @param string $keyField
     * @return array
     */
    public static function withOneModel(ActiveQuery $query,  array $idList , array $select = [], string $keyField = 'id'): array
    {
        if (!$idList || !$keyField) return [];
        $idArray = array_unique($idList);
        if (!$idArray) return [];
        if ($select) {
            if (!in_array($keyField, $select)) $select[] = $keyField;
            $query->select($select);
        }
        return $query->where([$keyField => $idArray])->indexBy($keyField)->asArray()->all();
    }

    /**
     * 绑定关联数据
     * @param array $list
     * @param array $withList
     * @param string $withName
     * @param array $select
     * @param string $keyField
     * @return array
     */
    public static function bindWithOneList(array $list, array $withList, string $withName, array $select = [], $keyField = 'id'): array
    {
        if (!$list || !$keyField || $withName) return $list;
        foreach ($list as $key => $value) {
            $withInfo = $withList[$value[$keyField]]  ?? [];
            if ($withInfo && $select) {
                $withInfo = array_intersect_key($withInfo, array_flip($select));
            }
            $value[$withName] = $withInfo?:null;
            $list[$key] = $value;
        }
        return $list;
    }
}
